/**
 * @Title: HomeActivity.java
 * @Package: com.jason.bluetooth.fingerprint.ui
 * @Descripton: TODO
 * @Author: Jason.Zhang zhangyujn1989ok@gmail.com
 * @Date: 2014年10月19日 上午8:19:23
 * @Version: V1.0
 */
package com.jason.bluetooth.fingerprint.ui;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.*;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;
import android_serialport_api.FingerprintManager;
import com.fgtit.fpcore.FPMatch;
import com.fgtit.reader.BluetoothReaderService;
import com.fgtit.reader.DeviceListActivity;
import com.jason.bluetooth.fingerprint.AppContext;
import com.jason.bluetooth.fingerprint.R;
import com.jason.bluetooth.fingerprint.adapter.HomeModelAdapter;
import com.jason.bluetooth.fingerprint.beans.OrganBean;
import com.jason.bluetooth.fingerprint.beans.RecordBean;
import com.jason.bluetooth.fingerprint.beans.UserBean;
import com.jason.bluetooth.fingerprint.beans.ui.FingerPrintBean;
import com.jason.bluetooth.fingerprint.beans.ui.ModelBean;
import com.jason.bluetooth.fingerprint.common.DialogHelper;
import com.jason.bluetooth.fingerprint.logic.DatbOrganSyncLogic;
import com.jason.bluetooth.fingerprint.logic.DatbRecordSyncLogic;
import com.jason.bluetooth.fingerprint.logic.DatbSelectOrganByIdSyncLogic;
import com.jason.bluetooth.fingerprint.utils.CodecUtils;
import com.jason.bluetooth.fingerprint.widget.LoadingDialog;
import org.kymjs.aframe.database.KJDB;
import org.kymjs.aframe.ui.BindView;
import org.kymjs.aframe.ui.KJActivityManager;
import org.kymjs.aframe.ui.activity.BaseActivity;
import org.kymjs.aframe.utils.StringUtils;
import org.kymjs.aframe.utils.SystemTool;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @ClassName: HomeActivity
 * @Description: 主页
 * @Author: Jason.Zhang zhangyujn1989ok@gmail.com
 * @Date: 2014年10月19日 上午8:19:23
 */
@SuppressLint("HandlerLeak")
public class HomeActivity extends BaseActivity {

    private static final String TAG = "HomeActivity";

    //蓝牙功能
    // Message types sent from the BluetoothChatService Handler
    public static final int MESSAGE_STATE_CHANGE = 1;
    public static final int MESSAGE_READ = 2;
    public static final int MESSAGE_WRITE = 3;
    public static final int MESSAGE_DEVICE_NAME = 4;
    public static final int MESSAGE_TOAST = 5;

    // Key names received from the BluetoothChatService Handler
    public static final String DEVICE_NAME = "device_name";
    public static final String TOAST = "toast";

    // Intent request codes
    public static final int REQUEST_CONNECT_DEVICE = 1;
    public static final int REQUEST_ENABLE_BT = 2;

    @BindView(id = R.id.home_gridview)
    private GridView mGridView;
    private TextView mUsernfoTextView;

    private HomeModelAdapter mHomeModelAdapter;
    private KJDB mKjdb;
    private LoadingDialog mProgressDialog;
    private boolean isAyncData = false;// 是否正在同步数据

    @BindView(id = R.id.header_title)
    private TextView mTitleTextView;

    private long mExitTime = 0;

    @Override
    public void setRootView() {
        setContentView(R.layout.activity_home);
    }

    // 初始化视图
    @Override
    protected void initWidget() {
        super.initWidget();
        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }
        mTitleTextView.setText("社区矫正");
        mKjdb = AppContext.getInstance().getKjdb();
        // mGridView = (GridView) findViewById(R.id.home_gridview);
        mHomeModelAdapter = new HomeModelAdapter(this);
        mGridView.setAdapter(mHomeModelAdapter);
        mGridView.setOnItemClickListener(new HomeModelItemClickListener());
        mGridView.setSelector(new ColorDrawable(Color.TRANSPARENT));

        mUsernfoTextView = (TextView) findViewById(R.id.home_info);
        mProgressDialog = new LoadingDialog(this);
        mProgressDialog.setMessage("数据正在加载中，请稍等...");
    }

    // 初始化数据
    @Override
    protected void initData() {
        super.initData();
        // 加载登录帐号下可选择的隶属机构
        if (SystemTool.checkNet(AppContext.getAppContext())) {
            // 初始化人员部门信息
            mKjdb.deleteByWhere(OrganBean.class, null);
            DatbOrganSyncLogic datbOrganSyncLogic = new DatbOrganSyncLogic(
                    AppContext.getInstance(), mRecordSyncHandler, false);
            datbOrganSyncLogic.execute();
            // 初始化矫正人员信息
            if (!mProgressDialog.isShowing()) {
                mProgressDialog.show();
            }
            initRecordSync(1);
        }
        updateUserInfo();
        initBoolue();
    }

    // 更新用户信息
    private void updateUserInfo() {
        mUsernfoTextView.setVisibility(View.VISIBLE);
        UserBean bean = AppContext.getInstance().getUserBean();
        StringBuffer buffer = new StringBuffer();
        if (AppContext.getInstance().isLogin()) {
            Log.i(TAG, bean.toString());
            String name = bean.getUserName();
            if (!StringUtils.isEmpty(name)) {
                buffer.append("登录用户：");
                buffer.append(name);
            }
            buffer.append("    隶属机构：" + bean.getOrgan());
            mUsernfoTextView.setText(buffer.toString());
        } else {
            mUsernfoTextView.setVisibility(View.GONE);
        }
    }

    // 档案同步
    private Handler mRecordSyncHandler = new Handler() {

        @Override
        public void handleMessage(android.os.Message msg) {
            if (mProgressDialog != null) {
                mProgressDialog.cancel();
            }
            isAyncData = false;
            int code = msg.arg1;
            switch (code) {
                case 0:
                    Toast.makeText(AppContext.getAppContext(),
                            "同步成功,共计" + msg.arg2 + "名，查看具体信息请到档案查询中查询",
                            Toast.LENGTH_LONG).show();
                    break;

                default:
                    Toast.makeText(AppContext.getAppContext(), "同步失败", Toast.LENGTH_SHORT).show();
                    break;
            }
            //开启蓝牙
            connectionBluetooth();
        }
    };

    // 进入指纹录入鉴权
    private Handler mAuthorityRecordHandle = new Handler() {

        @Override
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case 0:
                    Intent intent = new Intent(HomeActivity.this,
                            RecordActivity.class);
                    intent.putExtra(RecordActivity.RECORD_STATE,
                            RecordActivity.ADD_RECORD_STATE);
                    startActivity(intent);
                    break;
                case 1:
                    String error = (String) msg.obj;
                    Toast.makeText(AppContext.getAppContext(), error, Toast.LENGTH_SHORT).show();
                default:
                    Toast.makeText(AppContext.getAppContext(), "权限不足，无法访问", Toast.LENGTH_SHORT)
                            .show();
                    break;
            }
        }

        ;
    };

    private class HomeModelItemClickListener implements OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {
            ModelBean bean = (ModelBean) parent.getItemAtPosition(position);
            switch (bean.getIconId()) {
                case R.drawable.module_icon_luru_selector:
                    // TODO 指纹录入
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (SystemTool.checkNet(AppContext.getAppContext())) {
                        // 鉴权，只有权限的人才能指纹录入或者修改，此接口现在有问题？？？？？？
                        DatbSelectOrganByIdSyncLogic logic = new DatbSelectOrganByIdSyncLogic(
                                AppContext.getInstance(), mAuthorityRecordHandle, true);
                        logic.execute();
                    } else {
                        DialogHelper.openNetSettingsDialog(HomeActivity.this);
                    }
                    break;
                case R.drawable.module_icon_tongbu_selector:
                    // 档案同步
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    initRecordSync(2);
                    break;
                case R.drawable.module_icon_chaxun_selector:
                    // TODO 档案查询
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Intent intent = new Intent(HomeActivity.this,
                            RecordActivity.class);
                    intent.putExtra(RecordActivity.RECORD_STATE,
                            RecordActivity.QUERY_RECORD_STATE);
                    startActivity(intent);
                    break;
                case R.drawable.module_icon_fuwu_selector:
                    // TODO 社区服务
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Intent communityServiceIntent = new Intent(HomeActivity.this,
                            CommunityServiceActivity.class);
                    communityServiceIntent.putExtra("CommunityService", true);
                    startActivity(communityServiceIntent);
                    break;
                case R.drawable.module_icon_xuexi_selector:
                    // TODO 教育学习
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Intent studyServiceIntent = new Intent(HomeActivity.this,
                            CommunityServiceActivity.class);
                    studyServiceIntent.putExtra("CommunityService", false);
                    startActivity(studyServiceIntent);
                    break;
                case R.drawable.module_icon_baodao_selector:
                    // TODO 日常报到
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    startActivity(new Intent(HomeActivity.this,
                            DailyReportActivity.class));
                    break;
                case R.drawable.module_icon_zoufang_selector:
                    // TODO 工作走访
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    startActivity(new Intent(HomeActivity.this,
                            WorkVisitActivity.class));
                    break;
                case R.drawable.module_icon_qingjia_selector:
                    // TODO 外出请假
                    if (isAyncData) {
                        Toast.makeText(AppContext.getAppContext(), "数据正在同步中,请稍等...",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    startActivity(new Intent(HomeActivity.this,
                            LeaveOutActivity.class));
                    break;
                case R.drawable.module_icon_tongzhi_selector:
                    // TODO 工作通知
                    // workNotice();
                    startActivity(new Intent(HomeActivity.this,
                            WorkNotifyActivity.class));
                    break;
                case R.drawable.module_icon_tixing_selector:
                    // TODO 工作提醒
                    startActivity(new Intent(HomeActivity.this,
                            WorkRemindActivity.class));
                    break;
                case R.drawable.module_icon_peizhi_selector:
                    // TODO 系统配置
                    startActivity(new Intent(HomeActivity.this,
                            SettingActivity.class));
                    break;
                case R.drawable.module_icon_women_selector:
                    // TODO 关于我们
                    startActivity(new Intent(HomeActivity.this, AboutActivity.class));
                    break;

                default:
                    break;
            }
        }

    }

    // 档案同步
    private void initRecordSync(int state) {
        if (SystemTool.checkNet(AppContext.getAppContext())) {
            if (!isAyncData) {
                if (state == 2) {//点击加载的收
                    mProgressDialog.setTitle("数据同步");
                    mProgressDialog.setMessage("正在同步档案中，请稍等...");
                    mProgressDialog.show();
                }
                // 同步数据之前，需要把old data delete
                isAyncData = true;
                DatbRecordSyncLogic datbRecordSyncLogic = new DatbRecordSyncLogic(
                        AppContext.getInstance(), mRecordSyncHandler, true);
                datbRecordSyncLogic.execute();
            } else {
                Toast.makeText(AppContext.getAppContext(), "数据正在同步中",
                        Toast.LENGTH_SHORT).show();
            }
        } else {
            if (state == 2) {
                DialogHelper.openNetSettingsDialog(HomeActivity.this);
            }
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            if ((System.currentTimeMillis() - mExitTime) > 2000) {
                Toast.makeText(AppContext.getAppContext(), "再按一次退出应用",
                        Toast.LENGTH_SHORT).show();
                mExitTime = System.currentTimeMillis();
            } else {
                KJActivityManager.create().AppExit(HomeActivity.this);
//                FingerprintManager.getInstance().closeSerialPort();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mFingerBroadCastReceiver != null){
            unregisterReceiver(mFingerBroadCastReceiver);
        }
        if (mChatService != null) mChatService.stop();
    }

    //以下是蓝牙模块
    private final static byte CMD_PASSWORD=0x01;	//Password
    private final static byte CMD_ENROLID=0x02;		//Enroll in Device
    private final static byte CMD_VERIFY=0x03;		//Verify in Device
    private final static byte CMD_IDENTIFY=0x04;	//Identify in Device
    private final static byte CMD_DELETEID=0x05;	//Delete in Device
    private final static byte CMD_CLEARID=0x06;		//Clear in Device
    private final static byte CMD_ENROLHOST=0x07;	//Enroll to Host
    private final static byte CMD_CAPTUREHOST=0x08;	//Caputre to Host
    private final static byte CMD_MATCH=0x09;		//Match
    private final static byte CMD_WRITEFPCARD=0x0A;	//Write Card Data
    private final static byte CMD_READFPCARD=0x0B;	//Read Card Data
    private final static byte CMD_CARDSN=0x0E;		//Read Card Sn
    private final static byte CMD_GETSN=0x10;
    private final static byte CMD_FPCARDMATCH=0x13;

    private final static byte CMD_WRITEDATACARD = 0x14;    //Write Card Data
    private final static byte CMD_READDATACARD = 0x15;     //Read Card Data

    private final static byte CMD_PRINTCMD=0x20;		//Printer Print
    private final static byte CMD_GETBAT=0x21;
    private final static byte CMD_GETIMAGE=0x30;
    private final static byte CMD_GETCHAR=0x31;
    private final static byte CMD_UPCARDSN=0x43;

    private byte mDeviceCmd = 0x00;
    private boolean mIsWork = false;
    private byte mCmdData[] = new byte[10240];
    private int mCmdSize = 0;


    public byte mRefData[] = new byte[512];
    public int mRefSize = 0;
    public byte mRefData2[]=new byte[512];
    public int mRefSize2=0;
    public byte mMatData[] = new byte[512];
    public int mMatSize = 0;

    public static byte mRefList[][]=new byte[2048][512];
    public int	mRefCount=0;

    public byte mCardSn[] = new byte[4];
    public byte mCardData[] = new byte[4096];
    public int mCardSize = 0;

    public byte mBat[] = new byte[2];
    public byte mUpImage[] = new byte[73728];//36864
    public int mUpImageSize = 0;

    //
    public byte mRefCoord[] = new byte[512];
    public byte mMatCoord[] = new byte[512];

    public byte mIsoData[] = new byte[378];

    private Timer mTimerTimeout = null;
    private TimerTask mTaskTimeout = null;
    private Handler mHandlerTimeout;

    // Name of the connected device
    private String mConnectedDeviceName = null;
    // Array adapter for the conversation thread
    private ArrayAdapter<String> mConversationArrayAdapter;
    // String buffer for outgoing messages
    private StringBuffer mOutStringBuffer;
    // Local Bluetooth adapter
    private BluetoothAdapter mBluetoothAdapter = null;
    // Member object for the chat services
    private BluetoothReaderService mChatService = null;

    //开启打卡
    public static final String ACTION_BLUETOOTH_CARD_OPEN = "action_bluetooth_card_open";
    //关闭打卡
    public static final String ACTION_BLUETOOTH_CARD_CLOSE = "action_bluetooth_card_close";
    //打开状态
    public static final String ACTION_BLUETOOTH_CARD = "action_bluetooth_card";

    //开启指纹注册
    public static final String ACTION_BLUETOOTH_FINGER_OPEN_REGISTER = "action_bluetooth_finger_open_register";
    //开启指纹匹配
    public static final String ACTION_BLUETOOTH_FINGER_OPEN_MATCH = "action_bluetooth_finger_open_match";
    //关闭指纹
    public static final String ACTION_BLUETOOTH_FINGER_CLOSE = "action_bluetooth_finger_close";
    //指纹注册
    public static final String ACTION_BLUETOOTH_FINGER_REGISTER = "action_bluetooth_finger_register";
    //指纹匹配
    public static final String ACTION_BLUETOOTH_FINGER_MATCH = "action_bluetooth_finger_match";

    //人员选取之后通知
    public static final String ACTION_BLUETOOTH_RECORD_CHOOSE = "action_bluetooth_record_choose";

    //打开状态，成功失败，true,false
    public static final String CARD_STATE = "card_state";

    //指纹状态，成功失败，true,false
    public static final String FINGER_STATE = "finger_state";

    //指纹类型，默认0，如果是1，则表示是第一个指纹，如果是2,则表示是第二个指纹
    public static int FINGER_TYPE = 0;
    //当前选中的指纹信息
    public static FingerPrintBean FINGERPRINT_BEAN = null;

    //保存获取到的卡号或者指纹信息
    public static String CARD_VALUE = null;
    public static String FINGER_VALUE = null;

    //保存当前的finger id
    public static int  FINGER_ID = -1;

    public static RecordBean RECORD_INFO = null;

    public static boolean mBlueToothSate = true;

    private int mCardCount = 0;

    private TextView mConnectTextView;

    private void initBoolue() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mChatService = new BluetoothReaderService(this, mHandler);	// Initialize the BluetoothChatService to perform bluetooth connections
        mOutStringBuffer = new StringBuffer("");
        mConnectTextView = (TextView)findViewById(R.id.header_connect);
        mConnectTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent serverIntent = new Intent(HomeActivity.this, DeviceListActivity.class);
                startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
            }
        });
        //注册广播
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_BLUETOOTH_CARD_OPEN);
//        filter.addAction(ACTION_BLUETOOTH_CARD_CLOSE);
//        filter.addAction(ACTION_BLUETOOTH_CARD);
        filter.addAction(ACTION_BLUETOOTH_FINGER_OPEN_REGISTER);
        filter.addAction(ACTION_BLUETOOTH_FINGER_OPEN_MATCH);
//        filter.addAction(ACTION_BLUETOOTH_FINGER_CLOSE);
//        filter.addAction(ACTION_BLUETOOTH_FINGER_REGISTER);
//        filter.addAction(ACTION_BLUETOOTH_FINGER_MATCH);
        registerReceiver(mFingerBroadCastReceiver,filter);
        FPMatch.getInstance().InitMatch(2, "http://www.hzlj.net/");
    }


    private BroadcastReceiver mFingerBroadCastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(ACTION_BLUETOOTH_CARD_OPEN)){
                Log.i(TAG,"---->ACTION_BLUETOOTH_CARD_OPEN---001");
                CARD_VALUE = null;
                mCardCount = 0;
//                SendCommand(CMD_CARDSN,null,0);
            }else if(action.equals(ACTION_BLUETOOTH_FINGER_OPEN_REGISTER)){
                FINGER_VALUE = null;
                SendCommand(CMD_ENROLHOST,null,0);
            }else if(action.equals(ACTION_BLUETOOTH_FINGER_OPEN_MATCH)){
                Log.i(TAG, "---->ACTION_BLUETOOTH_FINGER_OPEN_MATCH---002");
                SendCommand(CMD_CAPTUREHOST,null,0);
            }
        }
    };

    @Override
    protected void onStart() {
        super.onStart();
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
            // Otherwise, setup the chat session
        } else {
            if (mChatService == null) setupChat();
        }
    }

    private void ensureDiscoverable() {
        if(true) Log.d(TAG, "ensure discoverable");
        if (mBluetoothAdapter.getScanMode() !=
                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            startActivity(discoverableIntent);
        }
    }

    private void AddStatusList(String text) {
        mConversationArrayAdapter.add(text);
    }

    private void SendCommand(byte cmdid,byte[] data,int size) {
        if(mIsWork)return;

        int sendsize=9+size;
        byte[] sendbuf = new byte[sendsize];
        sendbuf[0]='F';
        sendbuf[1]='T';
        sendbuf[2]=0;
        sendbuf[3]=0;
        sendbuf[4]=cmdid;
        sendbuf[5]=(byte)(size);
        sendbuf[6]=(byte)(size>>8);
        if(size>0) {
            for(int i=0;i<size;i++) {
                sendbuf[7+i]=data[i];
            }
        }
        int sum=calcCheckSum(sendbuf,(7+size));
        sendbuf[7+size]=(byte)(sum);
        sendbuf[8+size]=(byte)(sum>>8);

        mIsWork=true;
        TimeOutStart();
        mDeviceCmd=cmdid;
        mCmdSize=0;
        mChatService.write(sendbuf);

        switch(sendbuf[4]) {
            case CMD_PASSWORD:	//����
                break;
            case CMD_ENROLID:	//�Ǽǵ��豸
//                AddStatusList("Enrol ID ...");
                break;
            case CMD_VERIFY:	//���豸��֤
//                AddStatusList("Verify ID ...");
                break;
            case CMD_IDENTIFY:	//���豸����
//                AddStatusList("Search ID ...");
                break;
            case CMD_DELETEID:
//                AddStatusList("Delete ID ...");
                break;
            case CMD_CLEARID:
//                AddStatusList("Clear ...");
                break;
            case CMD_ENROLHOST:	//�Ǽǵ�����
//                AddStatusList("Enrol Template ...");
                break;
            case CMD_CAPTUREHOST:	//�ɼ�������
//                AddStatusList("Capture Template ...");
                break;
            case CMD_MATCH:	//�ȶ�
//                AddStatusList("Match Template ...");
                break;
            case CMD_WRITEFPCARD:	//д��
            case CMD_WRITEDATACARD:
//                AddStatusList("Write Card ...");
                break;
            case CMD_READFPCARD:	//����
            case CMD_READDATACARD:
//                AddStatusList("Read Card ...");
                break;
            case CMD_FPCARDMATCH:
//                AddStatusList("FingerprintCard Match ...");
                break;
            case CMD_CARDSN:		//�������к�
//                AddStatusList("Read Card SN ...");
                break;
            case CMD_GETSN:
//                AddStatusList("Get Device SN ...");
                break;
            case CMD_GETBAT:
//                AddStatusList("Get Battery Value ...");
                break;
            case CMD_GETIMAGE:
                mUpImageSize=0;
//                AddStatusList("Get Fingerprint Image ...");
                break;
            case CMD_GETCHAR:
//                AddStatusList("Get Fingerprint Data ...");
                break;
        }
    }

    private byte[] changeByte(int data) {
        byte b4 = (byte) ((data) >> 24);
        byte b3 = (byte) (((data) << 8) >> 24);
        byte b2 = (byte) (((data) << 16) >> 24);
        byte b1 = (byte) (((data) << 24) >> 24);
        byte[] bytes = { b1, b2, b3, b4 };
        return bytes;
    }

    private byte[] toBmpByte(int width, int height, byte[] data) {
        byte[] buffer = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(baos);

            int bfType = 0x424d;
            int bfSize = 54 + 1024 + width * height;
            int bfReserved1 = 0;
            int bfReserved2 = 0;
            int bfOffBits = 54 + 1024;

            dos.writeShort(bfType);
            dos.write(changeByte(bfSize), 0, 4);
            dos.write(changeByte(bfReserved1), 0, 2);
            dos.write(changeByte(bfReserved2), 0, 2);
            dos.write(changeByte(bfOffBits), 0, 4);

            int biSize = 40;
            int biWidth = width;
            int biHeight = height;
            int biPlanes = 1;
            int biBitcount = 8;
            int biCompression = 0;
            int biSizeImage = width * height;
            int biXPelsPerMeter = 0;
            int biYPelsPerMeter = 0;
            int biClrUsed = 256;
            int biClrImportant = 0;

            dos.write(changeByte(biSize), 0, 4);
            dos.write(changeByte(biWidth), 0, 4);
            dos.write(changeByte(biHeight), 0, 4);
            dos.write(changeByte(biPlanes), 0, 2);
            dos.write(changeByte(biBitcount), 0, 2);
            dos.write(changeByte(biCompression), 0, 4);
            dos.write(changeByte(biSizeImage), 0, 4);
            dos.write(changeByte(biXPelsPerMeter), 0, 4);
            dos.write(changeByte(biYPelsPerMeter), 0, 4);
            dos.write(changeByte(biClrUsed), 0, 4);
            dos.write(changeByte(biClrImportant), 0, 4);

            byte[] palatte = new byte[1024];
            for (int i = 0; i < 256; i++) {
                palatte[i * 4] = (byte) i;
                palatte[i * 4 + 1] = (byte) i;
                palatte[i * 4 + 2] = (byte) i;
                palatte[i * 4 + 3] = 0;
            }
            dos.write(palatte);

            dos.write(data);
            dos.flush();
            buffer = baos.toByteArray();
            dos.close();
            baos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer;
    }

    public byte[] getFingerprintImage(byte[] data,int width,int height) {
        if (data == null) {
            return null;
        }
        byte[] imageData = new byte[width*height * 2];
        for (int i = 0; i < (width*height); i++) {
            imageData[i * 2] = (byte) (data[i] & 0xf0);
            imageData[i * 2 + 1] = (byte) (data[i] << 4 & 0xf0);
        }
        byte[] bmpData = toBmpByte(width, height, imageData);
        return bmpData;
    }

    private void ReceiveCommand(byte[] databuf, int datasize) {
        if (mDeviceCmd == CMD_GETIMAGE) {
            memcpy(mUpImage, mUpImageSize, databuf, 0, datasize);
            mUpImageSize = mUpImageSize + datasize;
            if (mUpImageSize >= 15200) {
                byte[] bmpdata = getFingerprintImage(mUpImage, 152, 200);
                Bitmap image = BitmapFactory.decodeByteArray(bmpdata, 0, bmpdata.length);
//                fingerprintImage.setImageBitmap(image);
                mUpImageSize = 0;
                mIsWork = false;
//                AddStatusList("Display Image");
                /*
				try {
					Thread.currentThread();
					Thread.sleep(200);
				}catch (InterruptedException e){
					e.printStackTrace();
				}

				SendCommand(CMD_GETCHAR,null,0);
				*/
            }
        } else {
            memcpy(mCmdData, mCmdSize, databuf, 0, datasize);
            mCmdSize = mCmdSize + datasize;
            int totalsize = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00) + 9;
            if (mCmdSize >= totalsize) {
                mCmdSize = 0;
                mIsWork = false;
                if ((mCmdData[0] == 'F') && (mCmdData[1] == 'T')) {
                    switch (mCmdData[4]) {
                        case CMD_PASSWORD: {
                        }
                        break;
                        case CMD_ENROLID: {
                            if (mCmdData[7] == 1) {
                                //int id=mCmdData[8]+(mCmdData[9]<<8);
                                int id = (byte) (mCmdData[8]) + (byte) ((mCmdData[9] << 8) & 0xFF00);
//                                AddStatusList("Enrol Succeed:"+String.valueOf(id));
                            } else {
//                                AddStatusList("Enrol Fail");
                            }

                        }
                        break;
                        case CMD_VERIFY: {
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Verify Succeed");
                            } else {
//                                AddStatusList("Verify Fail");
                            }
                        }
                        break;
                        case CMD_IDENTIFY: {
                            if (mCmdData[7] == 1) {
                                int id = (byte) (mCmdData[8]) + (byte) ((mCmdData[9] << 8) & 0xFF00);
                                //int id=mCmdData[8]+(mCmdData[9]<<8);
//                                AddStatusList("Search Result:"+String.valueOf(id));
                            } else {
//                                AddStatusList("Search Fail");
                            }
                        }
                        break;
                        case CMD_DELETEID: {
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Delete Succeed");
                            } else {
//                                AddStatusList("Delete Fail");
                            }
                        }
                        break;
                        case CMD_CLEARID: {
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Clear Succeed");
                            } else {
//                                AddStatusList("Clear Fail");
                            }
                        }
                        break;
                        case CMD_ENROLHOST: {
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00) - 1;
                            boolean flag = false;
                            FINGER_VALUE = null;
                            if (mCmdData[7] == 1) {
                                if (mRefSize > 0) {
                                    memcpy(mRefData2, 0, mCmdData, 8, size);
                                    mRefSize2 = size;
                                } else {
                                    memcpy(mRefData, 0, mCmdData, 8, size);
                                    mRefSize = size;
                                }
                                if (mRefCount < 2048) {
                                    memcpy(mRefList[mRefCount], 0, mCmdData, 8, size);
                                    mRefCount++;
                                }
                                AddStatusListHex(mRefData, mRefSize);
                                FINGER_VALUE = CodecUtils.base64EncodeToString(mRefData);
                                if (FINGER_VALUE !=null){
                                    Log.i(TAG,"-----CMD_ENROLHOST--->FINGER_VALUE:" + FINGER_VALUE);
                                    flag = true;
                                }
                            }
                            Intent intent = new Intent(ACTION_BLUETOOTH_FINGER_REGISTER);
                            intent.putExtra(FINGER_STATE,flag);
                            sendBroadcast(intent);
                        }
                        break;
                        case CMD_CAPTUREHOST: {
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00) - 1;
                            boolean flag = false;
                            FINGER_ID = -1;
                            if (mCmdData[7] == 1) {
                                memcpy(mMatData, 0, mCmdData, 8, size);
                                mMatSize = size;
                                if (mRefList != null){
                                    for (int i = 0; i < mRefList.length;i ++){
                                        try{
                                            int score = FPMatch.getInstance().MatchTemplate(mRefList[i],mMatData);
                                            if (score > 50){
                                                flag = true;
                                                FINGER_ID = i;
                                            }
                                        }catch (Exception e){

                                        }
                                    }
                                }
                            }
                            Log.i(TAG,"Match:" + flag);
                            Intent i = new Intent(ACTION_BLUETOOTH_FINGER_MATCH);
                            i.putExtra(FINGER_STATE,flag);
                            sendBroadcast(i);
                        }
                        break;
                        case CMD_MATCH: {
                            int score = (byte) (mCmdData[8]) + ((mCmdData[9] << 8) & 0xFF00);
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Match Succeed:"+String.valueOf(score));
                            } else {
//                                AddStatusList("Match Fail");
                            }
                        }
                        break;
                        case CMD_WRITEFPCARD: {
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Write Fingerprint Card Succeed");
                            } else {
//                                AddStatusList("Write Fingerprint Card Fail");
                            }
                        }
                        break;
                        case CMD_READFPCARD: {
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00);
                            if (size > 0) {
                                memcpy(mCardData, 0, mCmdData, 8, size);
                                mCardSize = size;
//                                AddStatusList("Read Fingerprint Card Succeed");
                            } else {
//                                AddStatusList("Read Fingerprint Card Fail");
                            }
                        }
                        break;
                        case CMD_FPCARDMATCH: {
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Fingerprint Match Succeed");
                                int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00) - 1;
                                byte[] tmpbuf = new byte[size];
                                memcpy(tmpbuf, 0, mCmdData, 8, size);
//                                AddStatusList("Len="+String.valueOf(size));
                                AddStatusListHex(tmpbuf, size);
                                String txt = new String(tmpbuf);
//                                AddStatusList(txt);
                            } else {
//                                AddStatusList("Fingerprint Match Fail");
                            }
                        }
                        break;
                        case CMD_UPCARDSN:
                        case CMD_CARDSN: {
                            mCardCount ++;
                            CARD_VALUE = null;
                            boolean flag = false;
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xF0) - 1;
                            if (size > 0) {
                                memcpy(mCardSn, 0, mCmdData, 8, size);
//                                AddStatusList("Read Card SN Succeed:"+Integer.toHexString(mCardSn[0]&0xFF)+Integer.toHexString(mCardSn[1]&0xFF)+Integer.toHexString(mCardSn[2]&0xFF)+Integer.toHexString(mCardSn[3]&0xFF));
                                CARD_VALUE = CodecUtils.conver8Byte1To10String(mCardSn);
                                flag = true;
                            } else {
                                flag = false;
//                                AddStatusList("Read Card SN Fail");
                            }
                            Intent intent = new Intent(ACTION_BLUETOOTH_CARD);
                            intent.putExtra(CARD_STATE,flag);
                            sendBroadcast(intent);
//                            if (mCardCount == 2){
//                            }
                        }
                        break;
                        case CMD_WRITEDATACARD: {
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Write Card Data Succeed");
                            } else {
//                                AddStatusList("Write Card Data Fail");
                            }
                        }
                        break;
                        case CMD_READDATACARD: {
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00);
                            if (size > 0) {
                                memcpy(mCardData, 0, mCmdData, 8, size);
                                mCardSize = size;
//                                AddStatusList("Read Card Data Succeed");
                            } else {
//                                AddStatusList("Read Card Data Fail");
                            }
                        }
                        break;
                        case CMD_GETSN: {
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00) - 1;
                            if (mCmdData[7] == 1) {
                                byte[] snb = new byte[32];
                                memcpy(snb, 0, mCmdData, 8, size);
                                String sn = null;
                                try {
                                    sn = new String(snb, 0, size, "UNICODE");
                                } catch (UnsupportedEncodingException e) {
                                    e.printStackTrace();
                                }
//                                AddStatusList("SN:"+sn);
                            } else {
//                                AddStatusList("Get SN Fail");
                            }
                        }
                        break;
                        case CMD_PRINTCMD: {
                            if (mCmdData[7] == 1) {
//                                AddStatusList("Print OK");
                            } else {
//                                AddStatusList("Print Fail");
                            }
                        }
                        break;
                        case CMD_GETBAT: {
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00) - 1;
                            if (size > 0) {
                                memcpy(mBat, 0, mCmdData, 8, size);
//                                AddStatusList("Battery Value:"+Integer.toString(mBat[0]/10)+"."+Integer.toString(mBat[0]%10)+"V");
                            } else {
//                                AddStatusList("Get Battery Value Fail");
                            }
                        }
                        break;
                        case CMD_GETCHAR: {
                            int size = (byte) (mCmdData[5]) + ((mCmdData[6] << 8) & 0xFF00) - 1;
                            if (mCmdData[7] == 1) {
                                memcpy(mMatData, 0, mCmdData, 8, size);
                                mMatSize = size;
//                                AddStatusList("Len="+String.valueOf(mMatSize));
//                                AddStatusList("Get Data Succeed");
                                AddStatusListHex(mMatData, mMatSize);
                            } else {
//                                AddStatusList("Get Data Fail");
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_CONNECT_DEVICE:
                // When DeviceListActivity returns with a device to connect
                if (resultCode == RESULT_OK) {
                    // Get the device MAC address
                    String address = data.getExtras()
                            .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
//                    Toast.makeText(getApplicationContext(),"address:" + address,Toast.LENGTH_SHORT).show();
                    Log.i(TAG,"address:" + address);
                    // Get the BLuetoothDevice object
                    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                    // Attempt to connect to the device
                    mChatService.connect(device);
                }
                break;
            case REQUEST_ENABLE_BT:
                // When the request to enable Bluetooth returns
                if (resultCode == RESULT_OK) {
                    // Bluetooth is now enabled, so set up a chat session
                    setupChat();
                } else {
                    // User did not enable Bluetooth or an error occured
                    Log.d(TAG, "BT not enabled");
                    Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
                    finish();
                }
        }
    }

    private void setupChat() {
        Log.d(TAG, "setupChat()");
        // Initialize the array adapter for the conversation thread

        mChatService = new BluetoothReaderService(this, mHandler);    // Initialize the BluetoothChatService to perform bluetooth connections
        mOutStringBuffer = new StringBuffer("");                    // Initialize the buffer for outgoing messages
    }

    // The Handler that gets information back from the BluetoothChatService
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_STATE_CHANGE:
                    Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
                    switch (msg.arg1) {
                        case BluetoothReaderService.STATE_CONNECTED:
                            String tip = "已连接到：" + mConnectedDeviceName;
                            Toast.makeText(HomeActivity.this, tip, Toast.LENGTH_SHORT).show();
//                            mTitle.setText(R.string.title_connected_to);
//                            mTitle.append(mConnectedDeviceName);
                            mBlueToothSate = true;
//                            mConversationArrayAdapter.clear();
                            break;
                        case BluetoothReaderService.STATE_CONNECTING:
//                            mTitle.setText(R.string.title_connecting);
                            Toast.makeText(HomeActivity.this, getResources().getText(R.string.title_connecting), Toast.LENGTH_SHORT).show();
                            break;
                        case BluetoothReaderService.STATE_LISTEN:
                        case BluetoothReaderService.STATE_NONE:
//							mTitle.setText(R.string.title_not_connected);
                            Toast.makeText(HomeActivity.this, getResources().getText(R.string.title_not_connected), Toast.LENGTH_SHORT).show();
                            break;
                    }
                    break;
                case MESSAGE_WRITE:
                    byte[] writeBuf = (byte[]) msg.obj;
                    // construct a string from the buffer
                    //String writeMessage = new String(writeBuf);
                    //AddStatusList("Send:  " + writeMessage);
                    //AddStatusListHex(writeBuf,writeBuf.length);
                    break;
                case MESSAGE_READ:
                    byte[] readBuf = (byte[]) msg.obj;
                    ReceiveCommand(readBuf,msg.arg1);
                    //AddStatusList("Len="+Integer.toString(msg.arg1));
                    //AddStatusListHex(readBuf,msg.arg1);
                    break;
                case MESSAGE_DEVICE_NAME:
                    // save the connected device's name
                    mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
                    Toast.makeText(getApplicationContext(), "Connected to "
                            + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
                    break;
                case MESSAGE_TOAST:
                    Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
                            Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

    private void AddStatusListHex(byte[] data, int size) {
        String text = "";
        for (int i = 0; i < size; i++) {
            text = text + "," + Integer.toHexString(data[i] & 0xFF).toUpperCase();
        }
//		mConversationArrayAdapter.add(text);
    }

    private void memcpy(byte[] dstbuf, int dstoffset, byte[] srcbuf, int srcoffset, int size) {
        for (int i = 0; i < size; i++) {
            dstbuf[dstoffset + i] = srcbuf[srcoffset + i];
        }
    }

    private int calcCheckSum(byte[] buffer, int size) {
        int sum = 0;
        for (int i = 0; i < size; i++) {
            sum = sum + buffer[i];
        }
        return (sum & 0x00ff);
    }

    public void TimeOutStart() {
        if (mTimerTimeout != null) {
            return;
        }
        mTimerTimeout = new Timer();
        mHandlerTimeout = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                TimeOutStop();
                if (mIsWork) {
                    mIsWork = false;
//					AddStatusList("Time Out");
                }
                super.handleMessage(msg);
            }
        };
        mTaskTimeout = new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 1;
                mHandlerTimeout.sendMessage(message);
            }
        };
        mTimerTimeout.schedule(mTaskTimeout, 10000, 10000);
    }

    public void TimeOutStop() {
        if (mTimerTimeout != null) {
            mTimerTimeout.cancel();
            mTimerTimeout = null;
            mTaskTimeout.cancel();
            mTaskTimeout = null;
        }
    }

    //开启蓝牙
    private void connectionBluetooth() {
        new AlertDialog.Builder(HomeActivity.this).setTitle("开启蓝牙")
                .setMessage("是否打开蓝牙，扫描设备？").setCancelable(true)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent serverIntent = new Intent(HomeActivity.this, DeviceListActivity.class);
                        startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
                        dialog.dismiss();
                    }

                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {

                dialog.dismiss();
            }

        }).create().show();
    }
}